﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;


namespace Region
{
    
    public class DirItem
    {
      public delegate void EventHandlerOpen(DirItem Item);
      public delegate void EventHandlerAction(DirItem Item,DirActionItem Action);
      public class DirItemParam : IReadWriteObject
        {
            /// <summary>
            /// Список всех параметров
            /// Editor - Имя редактора, необязателен если зана Type String 
            /// Type - тип данных EPoleType
            /// Caption - Выводимое на именование String
            /// Value - Зачение Object
            /// Ex - дополнительные параметры передоваемые редактору
            /// Pr - Приоритет
            /// </summary>
            Dictionary<String, Dictionary<String, Object>> m_ParamList =new Dictionary<String, Dictionary<String, Object>>();
            /*Dictionary<String, Object> m_ParamValue = new Dictionary<String, Object>();
            Dictionary<String, EPoleType> m_Params = new Dictionary<String, EPoleType>();
            Dictionary<String, String> m_Editors = new Dictionary<String, String>();
            Dictionary<String, String> m_Captions = new Dictionary<String, String>();
            Dictionary<String, Object> m_ExProccessors = new Dictionary<String, Object>();*/
            class ParamsSort : IComparer<String>  
            {
              Dictionary<String, Dictionary<String, Object>> m_ParamList;
              public ParamsSort(Dictionary<String, Dictionary<String, Object>> ParamList){m_ParamList = ParamList;}
              int IComparer<String>.Compare( String x, String y )  
              {
                Int32 Pr1 =  m_ParamList[x].ContainsKey("Pr")?(Int32)m_ParamList[x]["Pr"]:0;
                Int32 Pr2 =  m_ParamList[y].ContainsKey("Pr")?(Int32)m_ParamList[y]["Pr"]:0;
                Int32 Pr = Pr1-Pr2;
                if (Pr!=0) 
                  return Pr;
                return String.Compare(x,y);
              }
            }
            public String[] getParams() 
            {
              String[] list = m_ParamList.Keys.ToArray();
              var cmp = new ParamsSort(m_ParamList);
              Array.Sort(list,cmp);
              return list; 
            }
            public Boolean isParam(String PoleName)
            {
              return m_ParamList.ContainsKey(PoleName);
            }
            public void addParams(String PoleName, EPoleType PoleType)
            { 
              if (!m_ParamList.ContainsKey(PoleName)) m_ParamList[PoleName] = new Dictionary<String, Object>();
              m_ParamList[PoleName]["Type"] = PoleType;
            }
            public void addParams(String PoleName, Dictionary<String, Object> Param)
            { 
              if (!m_ParamList.ContainsKey(PoleName)) m_ParamList[PoleName] = new Dictionary<String, Object>();
              foreach(var i in Param)
              {
                m_ParamList[PoleName][i.Key] = i.Value;
              }
            }
            public void delParams(String PoleName)
            {
              if (m_ParamList.ContainsKey(PoleName)) 
                m_ParamList.Remove(PoleName);
            }
            public String getEditor(String PoleName)
            {
              if (!m_ParamList.ContainsKey(PoleName)) throw new Exception("Указаный редактор '"+PoleName+"' не объявлен");
              Dictionary<String, Object> p = m_ParamList[PoleName];
              if (p.ContainsKey("Editor")) return (String)p["Editor"];
              if (p.ContainsKey("Type"))
              switch ((EPoleType)p["Type"])
              {
                  case EPoleType.Bool: return "CheckBox";
                  case EPoleType.Int32: return "NumericUpDown";
                  case EPoleType.Int64: return "NumericUpDown";
                  case EPoleType.RegionDate: return "DateTimePicker";
                  case EPoleType.String: return "TextBox";
              }
              return null;
            }
            public String getCaption(String PoleName)
            {
              if (!m_ParamList.ContainsKey(PoleName)) throw new Exception("Указаный редактор '"+PoleName+"' не объявлен");
              Dictionary<String, Object> p = m_ParamList[PoleName];
              if (p.ContainsKey("Caption")) return (String)p["Caption"];
              return PoleName;
            }
            public Object getExProccessor(String PoleName)
            {
              if (!m_ParamList.ContainsKey(PoleName)) throw new Exception("Указаный редактор '"+PoleName+"' не объявлен");
              Dictionary<String, Object> p = m_ParamList[PoleName];
              if (p.ContainsKey("Ex")) return p["Ex"];
              return null;
            }
            public void setEditor(String PoleName, String Editor)
            {
              if (!m_ParamList.ContainsKey(PoleName)) m_ParamList[PoleName] = new Dictionary<String, Object>();
              m_ParamList[PoleName]["Editor"] = Editor;
            }
            public void setCaption(String PoleName, String Caption) 
            {
              if (!m_ParamList.ContainsKey(PoleName)) m_ParamList[PoleName] = new Dictionary<String, Object>();
              m_ParamList[PoleName]["Caption"] = Caption;
            }
            public void setExProccessor(String PoleName, Object ExProccessor) 
            {
              if (!m_ParamList.ContainsKey(PoleName)) m_ParamList[PoleName] = new Dictionary<String, Object>();
              m_ParamList[PoleName]["Ex"] = ExProccessor;
            }
            
          #region Члены IReadWriteObject


            public object getPole(string PoleName)
            {
              if (!m_ParamList.ContainsKey(PoleName)) return false;
              return m_ParamList[PoleName]["Value"];
            }
            public bool setPole(string PoleName, object Value) 
            {
              if (!m_ParamList.ContainsKey(PoleName)) return false;
              Dictionary<String, Object> p = m_ParamList[PoleName];
              p["Value"] = Value;
              return true;
            }
            public EPoleType getPoleType(string PoleName)
            {
              return (EPoleType)m_ParamList[PoleName]["Type"];
            }
            public bool poleAccess(string PoleName) { return true; }
            public IDictionary<String, Object> getPoles(IList<String> Poles)
            {                
                var rPoles = new Dictionary<String, Object>();
                foreach (var p in Poles != null ? Poles : m_ParamList.Keys.ToList())
                    rPoles[p] = m_ParamList[p]["Value"];
                return rPoles;
            }
            public void setPoles(IDictionary<String, Object> Poles)
            {
                foreach (var p in Poles)
                    m_ParamList[p.Key]["Value"] = p.Value;                                
            }
            #endregion
        }
      public class DirActionItem
      {        
        public Image Icon;
        public String Caption;
        public EventHandlerAction OnAction;
        public void Action(DirItem Item)
        {
          if (OnAction!=null) OnAction(Item,this);
        }
        public Object Tag;
        public List<DirActionItem> SubItems;
        public DirActionItem(Image Icon,String Caption, EventHandlerAction OnAction,Object Tag)
        {
          this.Icon = Icon;
          this.Caption = Caption;
          this.OnAction = OnAction;
          this.Tag = Tag;         
        }
                
      }
        DirItem m_parent;
        List<DirItem> m_childs;
        Dictionary<String, Dictionary<Int32, Object>> m_Data;
        
        // События
        public event EventHandlerOpen OnOpen;
        public event EventHandlerOpen OnRefresh;
        public void Refresh(){if (OnRefresh!=null) OnRefresh(this); if (m_parent!=null) m_parent.Refresh();}
        //public event EventHandlerOpen OnPrint;
        Boolean m_Visible=true;
        public virtual Boolean Visible{get{return m_Visible;} set{m_Visible=value;}}
        public DirItem Parent { get { return m_parent; } }
        public List<DirItem> Childs { get { return new List<DirItem>(m_childs); } }        
        /// <summary> Возвращает колличество сталбцов при выводе реестра </summary>        
        public virtual Int32 getCountColumn() { return 1; }        
        /// <summary>Возвращает информацию о сталбцах</summary><param name="N">Номер столбца</param><param name="Role">Роль информации: Caption(String),Width(Int32)</param>        
        public virtual Object getColumn(Int32 N, String Role) { if (Role == "Caption") return ""; else if (Role == "Width") return 100; return null; }
        /// <summary> Параметры фильтрации реестра </summary>        
        public virtual DirItemParam getParams() { return null; }
        /// <summary> Получить список в соответствии с задаными фильтрами </summary>
        public virtual void Filter() { }
        
        public virtual Object getData(Int32 N, String Role)
        {
            if (m_Data == null) return null;
            if (!m_Data.ContainsKey(Role)) return null;
            if (!m_Data[Role].ContainsKey(N)) return null;
            return m_Data[Role][N];
        }

        public virtual void setData(Int32 N, String Role, Object Value)
        {
            if (m_Data == null) m_Data = new Dictionary<String, Dictionary<Int32, Object>>();
            if (!m_Data.ContainsKey(Role)) m_Data[Role] = new Dictionary<Int32, Object>();
            m_Data[Role][N] = Value;
        }
        
        public virtual void Open() { if (OnOpen != null) OnOpen(this); }
        //public virtual void Print() { if (OnPrint != null) OnPrint(this); }
        
        //public virtual bool IsPrint() { return OnPrint!=null; }
        
        public virtual bool IsDir() { return m_childs.Count > 0; }
        public virtual View ViewDir() { return View.LargeIcon; }
        public virtual bool IsParamPanel() { return false; }
        

        //public event EventHandler Changed;
        public bool Clear()
        {
            m_childs.Clear();
            return true;
        }
        public bool Add(DirItem item)
        {
            item.m_parent = this;
            m_childs.Add(item);
            return true;
        }
        void Init(String Caption, String ToolTip)
        {
            m_childs = new List<DirItem>();
            m_parent = null;
            setData(0, "Caption", Caption);
            setData(0, "ToolTip", ToolTip);
            setData(0, "IconLarge", Properties.Resources.Doc);
            setData(0, "IconSmall", Properties.Resources.Doc);
        }
        public DirItem(String Caption, String ToolTip) { Init(Caption, ToolTip); }
        public DirItem(String Caption) { Init(Caption, ""); }
        public DirItem() { Init("", ""); }


    };

}
